﻿using System.Data;
using System.Collections.Generic;

namespace DataSchema {


    partial class CollectionSchema
    {
        partial class CollectionDataTable
        {
        }
        #region STATIC
        static public DataSchema.CollectionSchema.ShotRow GetItemShot(DataSchema.CollectionSchema.ItemRow ir)
        {
            return (DataSchema.CollectionSchema.ShotRow)(ir.GetParentRow("FK_Shot_Item"));
        }
        

        static public DataSchema.CollectionSchema.CollectionEntityRow GetShotEntity(DataSchema.CollectionSchema.ShotRow sr)
        {
            return (DataSchema.CollectionSchema.CollectionEntityRow)sr.GetParentRow("FK_CollectionEntity_Shot");
        }

        public static DataSchema.CollectionSchema.ItemRow[] GetEntityItems(DataSchema.CollectionSchema.CollectionEntityRow ent)
        {
            List<DataSchema.CollectionSchema.ItemRow> l = new List<DataSchema.CollectionSchema.ItemRow>();
            DataSchema.CollectionSchema.ShotRow[] rs = GetEntityShots(ent);
            foreach (DataSchema.CollectionSchema.ShotRow rss in rs)
            {
                DataSchema.CollectionSchema.ItemRow[] ri = (DataSchema.CollectionSchema.ItemRow[])
                   rss.GetChildRows("FK_Shot_Item");
                l.AddRange(ri);
            }
            return l.ToArray();
        }

        public static DataSchema.CollectionSchema.ItemRow[] GetShotItems(DataSchema.CollectionSchema.ShotRow srow)
        {
            DataSchema.CollectionSchema.ItemRow[] ri = (DataSchema.CollectionSchema.ItemRow[])
                   srow.GetChildRows("FK_Shot_Item");
            return ri;
        }

        public static DataSchema.CollectionSchema.ShotRow[] GetEntityShots(DataSchema.CollectionSchema.CollectionEntityRow ent)
        {
            DataSchema.CollectionSchema.ShotRow[] rs = (DataSchema.CollectionSchema.ShotRow[])
                ent.GetChildRows("FK_CollectionEntity_Shot");
            return rs;
        }

        public static string PrepareString(string s)
        {
            if(s.Contains("'"))
            {
                string t = s.Replace("'", "''");
                return t;
            }
            return s;
        }


        #endregion

        #region PATHS RETRIEVING
     
        public string GetItemPath(DataSchema.CollectionSchema.ItemRow ir)
        {
            DataSchema.CollectionSchema.ShotRow sr = DataSchema.CollectionSchema.GetItemShot(ir);

            DataSchema.CollectionSchema.CollectionEntityRow er = DataSchema.CollectionSchema.GetShotEntity(sr);

            string entp;
            if(sr.IsLinkedToNull() || sr.LinkedTo == "")
                entp = GetEntityPath( er);
            else
                entp = sr.LinkedTo;

            string sh = sr.Name;
            if (sh.EndsWith("\\") == false)
                sh+="\\";
            string si = ir.Name;

            return entp + sh + si;
        }

        public string GetEntityPath(DataSchema.CollectionSchema.CollectionEntityRow ent)
        {
            if(ent.IsBurnedNull() == false && ent.Burned && DataSchema.Settings.SettingsMgr.DefaultCDDrive != "")
                return DataSchema.Settings.SettingsMgr.DefaultCDDrive + ent.Name + "\\";
            if(ent.IsPathNull() || ent.Path == "")
                return ((CollectionRow)(this.Collection.Rows[0])).Path + ent.Name + "\\";
            return ent.Path + ent.Name + "\\";
        }

        public string GetShotPath(DataSchema.CollectionSchema.ShotRow sr)
        {
            DataSchema.CollectionSchema.CollectionEntityRow er = GetShotEntity(sr);

            string entp;
            if(sr.IsLinkedToNull() || sr.LinkedTo == "")
                entp = GetEntityPath(er);
            else
                entp = sr.LinkedTo;

            string sh = sr.Name;


            return entp + sh;
        }
        #endregion

        #region FUNCTION TO MANAGE COLLECTION
        public DataSchema.CollectionSchema.ShotRow 
            AddNewShot(string name, string desc, string entity, string link, bool bPic)
        {
            string colname = this.Collection.Rows[0]["Name"].ToString();
            DataRow[] rs = Shot.Select("Name = '" + PrepareString(name) + "' AND EntityName = '" + PrepareString(entity) + "'");

            if (rs.Length != 0)
            {
                throw new DataSchema.DuplicatedObjectException("Shot " + name + " is duplicated in " + entity + " entity.", Objects.Shot);
            }


            DataSchema.CollectionSchema.ShotRow csr = null;
            csr = Shot.NewShotRow();
            csr.Name = name;
            csr.EntityName = entity;
            csr.Description = desc;
            csr.CollectionName = colname;
            csr.LinkedTo = link;
            csr.Pics = bPic;

            Shot.Rows.Add(csr);
            return csr;
        }

        public DataSchema.CollectionSchema.ItemRow AddNewItem(
            string name, long crc, long size, string shot, string entity)
        {
            DataRow[] rs = Item.Select("Name = '" + PrepareString(name) + "' AND Shot = '" + PrepareString(shot) + "' AND Entity = '" + PrepareString(entity) + "'");

            if(rs.Length != 0)
                throw new DataSchema.DuplicatedObjectException("Item " + name + " is duplicated in " + shot + " entity.", Objects.Item);
            

            DataSchema.CollectionSchema.ItemRow cir = Item.NewItemRow();
            cir.Name = name;
            cir.Entity = entity;
            cir.CRC32 = crc;
            cir.Size = size;
            cir.Shot = shot;
            Item.Rows.Add(cir);
            return cir;
        }
        
        public DataSchema.CollectionSchema.CollectionEntityRow AddNewEntity(string name, string csv)
        {
            if(CollectionEntity.Select("Name = '" + PrepareString(name) + "'").Length != 0)
            {
                throw new DuplicatedObjectException("Entity " + name + " is duplicated." , Objects.Entity);
            }
            DataSchema.CollectionSchema.CollectionEntityRow r = CollectionEntity.NewCollectionEntityRow();

            r.Name = name;
            r.Description = "";
            r.Path = "";
            r.CollectionName = ((DataSchema.CollectionSchema.CollectionRow)Collection.Rows[0]).Name;
            r.CSVFileName = csv;

            CollectionEntity.Rows.Add(r);
            return r;
        }

        public void AddNewIncomingFolder(string name)
        {
            if(IncomingFolders.Select("Name = '" + PrepareString(name) + "'").Length != 0)
            {
                throw new DuplicatedObjectException("IncomingFolder " + name + " is duplicated." , Objects.IncomingFolder);
            }
            DataSchema.CollectionSchema.IncomingFoldersRow r = this.IncomingFolders.NewIncomingFoldersRow();
            r.Name = name;
            this.IncomingFolders.Rows.Add(r);
        }
        #endregion

        #region FUNCTION TO RETRIVE INFO
        public IEnumerable<DataSchema.CollectionSchema.CollectionEntityRow> GetSelectedEntities()
        {
            DataView dv = new DataView(this.CollectionEntity, "Selected = true", "Name", DataViewRowState.CurrentRows);
            foreach(DataRowView rv in dv)
            {
                yield return (DataSchema.CollectionSchema.CollectionEntityRow)rv.Row;
            }
        }


        public List<DataSchema.CollectionSchema.ShotRow> GetShotsToBackUp()
        {
            List<DataSchema.CollectionSchema.ShotRow> list = new List<DataSchema.CollectionSchema.ShotRow>();
            DataSchema.CollectionSchema.BackupRow backup = (DataSchema.CollectionSchema.BackupRow)this.Backup.Rows[0];
            bool skip = false;

            DataView dv = new DataView(this.CollectionEntity, "Selected = true", "Name", DataViewRowState.CurrentRows);
            foreach(DataRowView rv in dv)
            {
                DataSchema.CollectionSchema.ShotRow[] sr = 
                    DataSchema.CollectionSchema.GetEntityShots((DataSchema.CollectionSchema.CollectionEntityRow)rv.Row);
                foreach(DataSchema.CollectionSchema.ShotRow shot in sr)
                {
                    skip = true;
                    if(!backup.IsRankNull() && backup.Rank > 0)
                    {
                        if(!shot.IsRankNull() && shot.Rank >= backup.Rank  )
                            skip = false;
                        else
                            continue;
                    }
                    if(!backup.IsOnlyCompletedNull() && backup.OnlyCompleted == true)
                    {
                        if(!shot.IsTotalNull() && !shot.IsHuntedNull() && shot.Total == shot.Hunted )
                            skip = false;
                        else
                            continue;
                    }
                    bool shallcontinue = false;
                    if(!backup.IsPicsNull()) 
                    {
                        if(backup.Pics == true)
                        {
                            if (!shot.IsPicsNull() && shot.Pics == true)
                                skip = false;
                            else
                                shallcontinue = true;
                                //continue;
                        }
                        else
                            if(shot.IsPicsNull() || shot.Pics == true)
                                continue;

                    }

                    if(!backup.IsVidsNull()) 
                    {
                        if( backup.Vids == true)
                        {
                            if(!shot.IsPicsNull() && shot.Pics == false)
                                skip = false;
                            else
                                if(shallcontinue)
                                    continue;
                        }
                        else if(shot.IsPicsNull() || shot.Pics == false)
                            continue;
                    }

                    if(!backup.IsASNull() && backup.AS == true)
                    {
                        if(!shot.IsASNull() && shot.AS == true)
                            skip = false;
                        else
                            continue;
                    }


                    if(skip == false)
                        list.Add(shot);
                }
            }
            return list;
        }

        public List<ItemRow> MatchByCRC32(long crc)
        {
            List<ItemRow> l = new List<ItemRow>();
            DataView dv = new DataView(this.Item, "CRC32 = " + crc.ToString(), "Name", DataViewRowState.CurrentRows);
            foreach (DataRowView rv in dv)
            {
                //yield return ((DataSchema.CollectionSchema.ItemRow)rv.Row);
                l.Add(((DataSchema.CollectionSchema.ItemRow)rv.Row));
            }
            return l;
        }



        public IEnumerable<string> GetSelectedIncomingFolders()
        {
            DataView dv = new DataView(this.IncomingFolders, "Selected = true", "Name", DataViewRowState.CurrentRows);
            foreach(DataRowView rv in dv)
            {
//                if(rv.Row.RowState == DataRowState.Deleted || rv.Row.RowState == DataRowState.Detached)
//                    continue;
                yield return ((DataSchema.CollectionSchema.IncomingFoldersRow)rv.Row).Name;
            }
        }
        
        public int GetSelectedIncomingFoldersCount()
        {
            DataView dv = new DataView(this.IncomingFolders, "Selected = true", "Name", DataViewRowState.CurrentRows);
            return dv.Count;
        }

        public string GetDefaultIncomingFolder()
        {
            if(this.IncomingFolders.Rows.Count > 0)
                return this.IncomingFolders.Rows[0]["Name"].ToString();
            return "";
        }

        public string GetLastHuntDT()
        {
            if (!((DataSchema.CollectionSchema.CollectionRow)(Collection.Rows[0])).IsLastHuntDTNull())
                return ((DataSchema.CollectionSchema.CollectionRow)(Collection.Rows[0])).LastHuntDT.ToLongDateString();
            return "Not hunted yet";
        }

        public void UpdateLastHuntDT()
        {
            ((DataSchema.CollectionSchema.CollectionRow)(Collection.Rows[0])).LastHuntDT = System.DateTime.Now;
        }

        #endregion

        #region STATIC
        static public bool IsItemPic(string name)
        {
            if(name.ToLower().EndsWith("jpg") || name.ToLower().EndsWith("jpeg"))
                return true;
            return false;
        }
        static public bool IsItemVid(string name)
        {
            if (name.ToLower().EndsWith("avi") || name.ToLower().EndsWith("mpg") || name.ToLower().EndsWith("mpeg") || name.ToLower().EndsWith("wmf"))
                return true;
            return false;
        }

        #endregion

        #region SUMMARY
        public void UpdateSummary()
        {
            foreach(CollectionEntityRow er in this.GetSelectedEntities())
            {
                uint shotcount = 0;
                uint entcount = 0;

                er.EntitySize = EntitySize(er.Name);

                ShotRow[] srs = GetEntityShots(er);
                foreach(ShotRow sr in srs)
                {
                    ItemRow[] rs = GetShotItems(sr);
                    
                    shotcount = 0;

                    foreach (ItemRow r in rs)
                    {
                        if (r.Exists == true)
                        shotcount++;
                    }
                    sr.Hunted = shotcount;

                    if(sr.Hunted == sr.Total)
                    {
                        DataSchema.CollectionSchema.FinishedShotsRow finshot = this.FinishedShots.NewFinishedShotsRow();
                        finshot.Name = sr.Name;
                        finshot.Date = System.DateTime.Now;
                        this.FinishedShots.AddFinishedShotsRow(finshot);
                    }

                    entcount += shotcount;
                }

                er.Hunted = entcount;

                if (er.Hunted == er.Total)
                {
                    er.Completed = true;
                    DataSchema.CollectionSchema.FinishedEntitiesRow finent = this.FinishedEntities.NewFinishedEntitiesRow();
                    finent.Name = er.Name;
                    finent.Date = System.DateTime.Now;
                    this.FinishedEntities.AddFinishedEntitiesRow(finent);
                }
            }
        }

        public double TotalHunted
        {
            get
            {
                object sumObject;
                sumObject = Item.Compute("Count(Exists)", "Exists = true");
                double sumsize = 0;
                if(sumObject != null && sumObject!= System.DBNull.Value)
                {
                    sumsize = double.Parse(sumObject.ToString());
                }
                return sumsize;
            }
        }
        public double TotalSize
        {
            get
            {
                object sumObject;
                sumObject = Item.Compute("Sum(Size)", "Exists = true");
                double sumsize = 0;
                if(sumObject != null && sumObject!= System.DBNull.Value)
                {
                    sumsize = double.Parse(sumObject.ToString());
                }
                return sumsize;
            }
        }
        public ulong EntitySize(string ent)
        {
                object sumObject;
                sumObject = this.Item.Compute("Sum(Size)", "Exists = true and Entity = '" + ent + "'");
                ulong sumsize = 0;
                if(sumObject != null && sumObject!= System.DBNull.Value)
                {
                    sumsize = ulong.Parse(sumObject.ToString());;
                }
                else
                    sumsize = 0;
            return sumsize ;

        }
        #endregion

        #region PRIVATE
    	private string GetSize(long size)
	    {

		    double s = size;

		    string[] format = new string[] {"{0} bytes", "{0} KB","{0} MB", "{0} GB", "{0} TB", "{0} PB", "{0} EB"};

		    int i = 0;

		    while (i < format.Length && s >= 1024) {

			    s = (int) (100 * s / 1024) / 100.0;
			    i++;
		    }
		    return string.Format(format[i],s);
	    }
        #endregion

        #region COLLECTION MODIFICATION
        public void BeginValidation(DataSchema.CollectionSchema.CollectionEntityRow ent_row)
        {
            DataSchema.CollectionSchema.ShotRow[] rs = DataSchema.CollectionSchema.GetEntityShots(ent_row);
            DataSchema.CollectionSchema.ItemRow[] rsi = DataSchema.CollectionSchema.GetEntityItems(ent_row);

            ((DataSchema.CollectionSchema.CollectionEntityRow)(ent_row)).Hunted = 0;
            foreach (DataSchema.CollectionSchema.ShotRow sr in rs)
            {
                sr.Hunted = 0;
            }

            foreach (DataSchema.CollectionSchema.ItemRow ir in rsi)
            {
                ir.Exists = false;
            }
        }
        
        public void NewItemWasHunted(DataSchema.CollectionSchema.ItemRow itemrow)
        {
            DataSchema.CollectionSchema.ShotRow shotrow = DataSchema.CollectionSchema.GetItemShot(itemrow); 
            DataSchema.CollectionSchema.CollectionEntityRow entrow = GetShotEntity(shotrow);
            itemrow.Exists = true;
            shotrow.Hunted++;
            shotrow.Pics = IsItemPic(itemrow.Name);
        }
        #endregion
    }
}
